package top.techqi.core.util

import android.annotation.SuppressLint
import android.content.res.ColorStateList
import android.content.res.Resources
import android.graphics.Color
import android.graphics.Typeface
import android.graphics.drawable.Drawable
import androidx.annotation.AnyRes
import androidx.annotation.ArrayRes
import androidx.annotation.BoolRes
import androidx.annotation.ColorRes
import androidx.annotation.DimenRes
import androidx.annotation.DrawableRes
import androidx.annotation.FontRes
import androidx.annotation.FractionRes
import androidx.annotation.IntegerRes
import androidx.annotation.PluralsRes
import androidx.annotation.StringRes
import androidx.core.content.res.ResourcesCompat
import androidx.core.graphics.drawable.toDrawable
import top.techqi.core.App
import top.techqi.core.BuildConfig

/** 资源工具类 */
@Suppress("unused")
object ResUtil {
    @SuppressLint("DiscouragedApi")
    fun getResourceId(name: String, type: String, pkg: String = App.packageName): Int {
        return safeGet({ getIdentifier(name, type, pkg) }, 0)
    }

    fun getResourceName(@AnyRes resId: Int): String {
        return safeGet({ getResourceName(resId) }, "")
    }

    fun getBoolean(@BoolRes resId: Int): Boolean {
        return safeGet({ getBoolean(resId) }, false)
    }

    fun getInteger(@IntegerRes resId: Int): Int {
        return safeGet({ getInteger(resId) }, 0)
    }

    fun getFloat(@DimenRes resId: Int): Float {
        return safeGet({ ResourcesCompat.getFloat(this, resId) }, 0F)
    }

    fun getFraction(@FractionRes resId: Int, base: Int = 1, pbase: Int = 1): Float {
        return safeGet({ getFraction(resId, base, pbase) }, 0F)
    }

    fun getDimension(@DimenRes resId: Int): Float {
        return safeGet({ getDimension(resId) }, 0F)
    }

    fun getDimensionPixelOffset(@DimenRes resId: Int): Int {
        return safeGet({ getDimensionPixelOffset(resId) }, 0)
    }

    fun getDimensionPixelSize(@DimenRes resId: Int): Int {
        return safeGet({ getDimensionPixelSize(resId) }, 0)
    }

    fun getColor(@ColorRes resId: Int, theme: Resources.Theme? = null): Int {
        return safeGet({ ResourcesCompat.getColor(this, resId, theme) }, Color.TRANSPARENT)
    }

    fun getColorStateList(@ColorRes resId: Int, theme: Resources.Theme? = null): ColorStateList {
        return safeGet(
            { ResourcesCompat.getColorStateList(this, resId, theme) },
            ColorStateList.valueOf(Color.TRANSPARENT)
        )
    }

    fun getDrawable(@DrawableRes resId: Int, theme: Resources.Theme? = null): Drawable {
        return safeGet(
            { ResourcesCompat.getDrawable(this, resId, theme) },
            Color.TRANSPARENT.toDrawable()
        )
    }

    fun getString(@StringRes resId: Int, vararg formatArgs: Any): String {
        return safeGet({
            if (formatArgs.isEmpty()) getString(resId)
            else getString(resId, *formatArgs)
        }, "")
    }

    fun getQuantityString(@PluralsRes resId: Int, quantity: Int, vararg formatArgs: Any): String {
        return safeGet({
            if (formatArgs.isEmpty()) getQuantityString(resId, quantity)
            else getQuantityString(resId, quantity, *formatArgs)
        }, "")
    }

    fun getIntArray(@ArrayRes resId: Int): IntArray {
        return safeGet({ getIntArray(resId) }, intArrayOf())
    }

    fun getStringArray(@ArrayRes resId: Int): Array<String> {
        return safeGet({ getStringArray(resId) }, arrayOf())
    }

    fun getFont(@FontRes resId: Int): Typeface {
        return safeGet({ ResourcesCompat.getFont(App.INSTANCE, resId) }, Typeface.DEFAULT)
    }

    private inline fun <T> safeGet(action: Resources.() -> T?, defValue: T): T {
        return try {
            action(App.INSTANCE.resources)
        } catch (ex: Exception) {
            if (BuildConfig.DEBUG) {
                throw ex
            }
            null
        } ?: defValue
    }
}
